iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
Software Development

TW-OCR:高準確率繁體中文公文辨識與版面重建系統系列 第 1

Day 1|為什麼我想重做一套繁體中文公文 OCR?

  • 分享至 

  • xImage
  •  

如果今天只是要辨識一張乾淨的 A4 文件,我大概不會想自己做 OCR。

市面上已經有非常多成熟的 OCR 工具,開源、商用、雲端 API 都有。丟一張圖片進去,把文字抓出來,這件事情本身早就不是什麼新技術。

但當我要處理的東西變成台灣政府公文之後,事情就開始不太一樣了。

這也是我開始這個專案的原因。

接下來 30 天,我想把這段研發過程完整拆開來寫。

不是只介紹「怎麼 Fine-tune 一個 OCR 模型」,而是從資料、文字偵測、版面分析、VLM 辨識,一路寫到 GPU 記憶體、多人併發,甚至包含一些最後被我放棄的技術方案。

這篇先從最前面的問題開始:

為什麼我不直接用現成 OCR?


公文看起來只是文字,實際上不是

一開始接觸這個問題時,很容易把它想成:

PDF → OCR → 文字

但真的把政府文件丟進系統後,我很快發現,「把字讀出來」其實只是問題的一部分。

我目前處理的語料包含:

  • 監察院調查報告
  • 立法院預算書
  • 政府機關公告

這些文件都有一個共同點:

它們是設計給人看的,不是設計給 OCR 看的。

對人來說,我們看到一張表格,很自然就知道哪個數字屬於哪一欄;看到直排欄位,也知道閱讀方向要換。

但對程式來說,它看到的其實只是一堆 pixel。

而在實際整理資料的過程中,我把最常遇到的問題歸納成四類。


第一個問題:繁體中文本身就沒有那麼單純

這個系統主要面對的是繁體中文。

除了常見中文字之外,政府文件裡還會出現:

  • 罕用字
  • 異體字
  • 人名
  • 地名
  • 法規名稱
  • 案號
  • 數字與中文字混合內容

如果只是一般文章,偶爾錯一個字可能還能接受。

但如果 OCR 的結果後面還要拿去做:

  • 文件檢索
  • RAG
  • AI 審查
  • 資料結構化
  • 案號或金額擷取

那一個字的錯誤就可能不只是 typo。

例如金額、案號、法條名稱辨識錯誤,後面的 AI 即使再聰明,拿到的 source 本身就是錯的。

所以我真正想知道的,不是:

「這個模型看起來會不會讀中文?」

而是:

能不能真的把錯誤率壓到一個可以進入後續資訊系統的程度?

這也變成我後來第一個研究問題:

能不能做到平均每 1,000 個字,錯不到 10 個字?

換成 OCR 常用的指標,就是:

CER(Character Error Rate)能不能低於 1%?

CER 到底怎麼算,以及為什麼只看「準確率 99%」其實很危險,我會留到後面的 Benchmark 篇再談。


第二個問題:公文同時存在橫書和直書

這是一般文章型 OCR 很容易忽略的地方。

政府文件裡可能同一頁同時出現:

正文是橫書,表格欄位卻是直書。

例如預算表、統計表、分類欄位,為了節省水平空間,標題很常被轉成直排。

對人類來說只是把頭稍微歪一下。

但對 OCR 來說:

「這是一串由左到右的文字?」

還是:

「這是一串由上到下的文字?」

是兩個完全不同的問題。

因此我最後並沒有嘗試讓一個辨識流程硬吃全部內容,而是開始把不同型態的文字分流處理。

這也是後面整套架構會逐漸變複雜的第一個原因。


第三個問題:表格遠比正文麻煩

如果只拿一般文章測 OCR,很容易得到一個非常漂亮的數字。

但真正的公文不是只有文章。

裡面可能會出現:

  • 大量格線
  • 合併儲存格
  • 跨欄標題
  • 數字對齊
  • 前導點
  • 多層表頭
  • 直書欄名

這時候問題已經不只是:

「這裡寫了什麼?」

而是:

「這段文字到底屬於哪一格?」

假設 OCR 把整張表裡的字全部認對,但是欄位位置全部亂掉,對後面的程式而言,那張表基本上還是不能用。

因此我要保留的不只是文字。

最後希望輸出的其實是:

文字 + 版面座標 + 表格結構

從這裡開始,這個問題就已經慢慢從「OCR」變成「Document Understanding」。


第四個問題:一頁裡什麼東西都有

政府文件很常見的另一種情況是:

多欄 + 圖片 + 表格 + Header/Footer + 正文全部混在一起。

如果只是偵測出所有文字框,還是不夠。

系統還要知道:

  • 哪一塊是正文?
  • 哪一塊是表格?
  • 哪一塊是圖片?
  • 哪個是 Header?
  • 哪個是 Footer?
  • 文字應該按照什麼順序讀?

否則就會發生另一種很典型的問題:

每個字都認對了,但組回來的文章順序是錯的。

所以後來我開始把「文字在哪裡」、「這塊東西是什麼」、「這個字怎麼讀」拆成不同問題。

而不是期待一個模型從頭包到尾。


還有一個現實條件:不是所有 OCR 引擎都能選

除了技術條件之外,這個專案還有一個實際限制:

排除中國大陸來源的辨識引擎。

也就是說,技術選型不能只看排行榜上誰最準。

模型來源、授權、能不能自己部署、GPU 資源、後續能不能維護,都要一起考慮。

這也是為什麼最後這套系統沒有變成:

「找一個 Benchmark 第一名的 OCR,裝起來,結案。」

而是慢慢長成一套自己的 Pipeline。


所以,我最後沒有做「一個 OCR 模型」

這大概是這個系列最重要的觀念之一。

我原本以為我要解的是:

圖片 → OCR Model → 文字

最後實際做出來的東西比較接近:

https://ithelp.ithome.com.tw/upload/images/20260826/20183446SK2Wcm3ErT.png

目前整套流程實際包含了 CRAFT、Heron、PaliGemma2,以及不同用途的 LoRA。

但這些名稱今天先不用記。

後面我會一層一層拆。


我真正想回答的是六個問題

做到後來,我把整個研究整理成六個很實際的問題:

  1. OCR 能不能真的做到 CER < 1%?
  2. 在自己的測試資料變準,遇到沒看過的公文還會準嗎?
  3. GPU 記憶體能不能降,而且不要犧牲準確率?
  4. 是不是有模型被重複載進 GPU,白白浪費記憶體?
  5. 一張 GPU 到底能同時處理幾份文件?Concurrent 越高真的越快嗎?
  6. 換成 vLLM 這種推論引擎,吞吐量真的會比較高嗎?

有些答案跟我原本想的一樣。

有些完全相反。

尤其是最後一題。

我一開始非常看好 vLLM。

最後卻把它拿掉了。

這部分後面會寫。


這 30 天我會寫什麼?

這系列不會只是一套「安裝 OCR 套件教學」。

我比較想記錄的是:

一個 OCR 系統到底怎麼從「模型跑得動」,一路做到「真的可以放進服務裡」。

會包含:

資料怎麼做、Benchmark 怎麼設計、LoRA 怎麼訓練、為什麼有一次模型看似收斂其實根本沒看完資料、怎麼把 GPU 記憶體砍下來、怎麼測多人併發,以及那些花了很多時間最後卻證明不值得採用的方案。

目前這個專案仍在持續進行。

所以這 30 天與其說是一份「成功案例教學」,我更希望它像是一份工程紀錄:

做了什麼、為什麼做、量到了什麼,以及哪些結論其實還不能下。


Day 1 小結

今天先不碰模型。

如果只留下一件事情,我希望是這句:

真實世界的 OCR,問題通常不是「模型會不會認字」,而是你到底要讓它讀什麼樣的文件。

繁體中文、直書、表格、多欄版面、閱讀順序……

當這些條件全部疊在一起後,我需要解的已經不是單純的文字辨識問題。

而是一整套文件理解流程。

明天 Day 2,我會先談一件我後來覺得比選模型更重要的事情:

OCR 到底怎樣才算「準」?

如果模型號稱 99% 準確率,那真的代表 1000 個字只會錯 10 個嗎?

以及一個在自己的測試集非常漂亮的分數,為什麼到了真正沒看過的公文上,可能完全不是那回事。


下一篇
Day 2|OCR 到底怎樣才算「準」?99% 準確率可能什麼都沒告訴你
系列文
TW-OCR:高準確率繁體中文公文辨識與版面重建系統3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言